//-----------------------------------------------------------------------
// <copyright file="CreateActiveDirectoryUserTest.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Unit tests for ActiveDirectory tasks.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Test
{
    using System;
    using System.IO;
    using Microsoft.Sdc.Tasks.Configuration;
    using Microsoft.Sdc.Tasks.ActiveDirectory;
    using Microsoft.Build.Framework;
    using Microsoft.Sdc.Tasks.Configuration.ActiveDirectory;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Unit tests for ActiveDirectory tasks.
    /// </summary>
    [TestClass]
    public class ActiveDirectory
    {
        public ActiveDirectory()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get { return this.testContextInstance; }
            set { this.testContextInstance = value; }
        }


        [TestMethod]
        public void CreateActiveDirectoryUsersAndGroups()
        {
            Tasks.ActiveDirectory.User.Create task = new Tasks.ActiveDirectory.User.Create();

            //Generate a new random username
            Guid guid = Guid.NewGuid();
            string username = guid.ToString();
            username = username.Replace("-", "").Substring(0, 11);

            if (User.Exists(username))
            {
                Assert.Fail("User already existed");
            }

            task.UserName = username;
            task.Password = "1234$abcd";
            bool taskReturnValue = task.Execute();
            Assert.IsTrue(taskReturnValue, "CreateActiveDirectoryUserTest");

            //Check the user now exists
            bool userExists = User.Exists(username);
            Assert.IsTrue(userExists, "CreateActiveDirectoryUserTest");

            // check password expiry flag
            User u = User.Load(username);
            Assert.IsTrue(u.PasswordExpires, "User password expiry is set to false");

            // change user properties
            task.PasswordExpires = false;
            task.EnsureUser = true;
            taskReturnValue = task.Execute();
            Assert.IsTrue(taskReturnValue, "CreateActiveDirectoryUserTest - Ensure User");

            u = User.Load(username);
            Assert.IsFalse(u.PasswordExpires, "User password expiry is set to true");

            string groupName = this.CreateGroup();

            this.AddUserToGroup(username, groupName);

            //check the user is in the group
            u = User.Load(username);
            
            if (!u.IsInGroup(groupName))
            {
                Assert.Fail("Created user is not in the created group");
            }

            try
            {
                this.AddUserToGroupAgain(username, groupName);
                Assert.Fail("Should not have allowed me to add the same user to the group again.");
            }

            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw ApplicationException on attempting to add user to group again.");
            }

            this.AddUserToGroupEnsuring(username, groupName);

            //Now delete the user
            User user = User.Load(username);
            bool userDeleted = user.Delete();
            Assert.IsTrue(userDeleted, "CreateActiveDirectoryUserTest");

            //Now delete the group
            Group group = Group.Load(groupName);
            bool groupDeleted = group.Delete();
            Assert.IsTrue(groupDeleted, "CreateActiveDirectoryGroupTest group now deleted");
        }

        private void AddUserToGroup(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();

            task.UserName = userName;
            task.GroupName = new string[] { groupName };
            bool taskReturn = task.Execute();

            Assert.IsTrue(taskReturn, "AddActiveDirectoryUserToGroup Execute returned false");

        }

        private void AddUserToGroupEnsuring(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();

            task.UserName = userName;
            task.GroupName = new string[] { groupName };
            task.EnsureUserIsInGroup = true;
            bool taskReturn = task.Execute();
            Assert.IsTrue(taskReturn, "AddActiveDirectoryUserToGroup Execute returned false");
        }

        private void AddUserToGroupAgain(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();

            task.UserName = userName;
            task.GroupName = new string[] { groupName };
            bool taskReturn = task.Execute();
            //Check that user cannot be added twice
            Assert.IsFalse(taskReturn, "AddActiveDirectoryUserToGroupTest add local user to local group");
        }

        private string CreateGroup()
        {
            Tasks.ActiveDirectory.Group.Create task = new Tasks.ActiveDirectory.Group.Create();

            //Generate a new random group
            Guid guid = Guid.NewGuid();
            string groupName = guid.ToString();
            groupName = groupName.Replace("-", "").Substring(0, 11);

            if (Group.Exists(groupName))
            {
                Assert.Fail("Group already existed");
            }

            task.GroupName = groupName;
            bool taskReturnValue = task.Execute();
            Assert.IsTrue(taskReturnValue, "CreateActiveDirectoryGroupTest create group");

            //Check the group now exists
            bool groupExists = Group.Exists(groupName);
            Assert.IsTrue(groupExists, "CreateActiveDirectoryGroupTest group now exists");
            return groupName;
        }
    }
}

